import render_helper from "./render_helper.mjs";
import thin_render from "./thin_render.mjs";
import render_content from "./render_content.mjs";
import datarover from "./datarover.mjs";
import { nearest_data } from "./nearest.mjs";
import string_template from "./string_template.mjs";
import { thin } from "../thin3.mjs";
import { datatimeformat } from "./datetimeformat.mjs";

/**
 * 对象模板渲染函数
 * @param {HTMLElement} container - 容器元素
 * @param {Object} template - 模板对象
 */
export default function object_template(container, template) {
  let d;
  // 获取数据源,支持三种方式:
  // 1. 函数方式
  if (typeof template.data === "function") {
    d = template.data({ container, template, data: nearest_data(container) });
  }
  // 2. 直接数据 + 可选数据路径
  else if (template.data !== undefined) {
    if (template.datapath) {
      d = datarover(template.data, template.datapath);
    } else d = template.data;
  }
  // 3. 从容器获取数据路径
  else if (template.datapath !== undefined) {
    d = datarover(container, template.datapath);
    // 如果数据不存在则初始化为空对象
    if (typeof d === "undefined") {
      datarover(container, template.datapath, {});
      d = datarover(container, template.datapath);
    }
  }

  // 支持数组数据的渲染
  if (Array.isArray(d)) {
    d.forEach((data, i) => {
      render(data, i);
    });
  } else {
    render(d);
  }

  /**
   * 渲染函数
   * @param {*} data - 渲染数据
   * @param {number} rowindex - 行索引(用于数组渲染)
   */
  function render(data, rowindex) {
    // 条件渲染判断
    if (!template.hasOwnProperty("when")) {
      do_render();
    }
    // when为函数时的条件判断
    else if (typeof template.when === "function") {
      if (
        template.when({
          container: container,
          template: template,
          data: data || nearest_data(container),
        })
      )
        do_render();
    }
    // when为字符串时的条件判断(数据路径)
    else if (typeof template.when === "string") {
      if (datarover(container, template.when)) {
        do_render();
      }
    }
    // when为true时直接渲染
    else if (template.when) do_render();

    /**
     * 执行实际的渲染逻辑
     */
    function do_render() {
      // 获取要创建的元素名称(模板对象的第一个key)
      let element_name = Object.keys(template)[0];
      let element = document.createElement(element_name);
      container.appendChild(element);

      // 设置元素的数据属性
      if (data !== undefined) {
        element.thin_data = data;
        if (rowindex) element.thin_rowindex = rowindex;
      }

      // 执行渲染前的钩子函数
      template?.before?.({ container: element, data: nearest_data(element) });

      // 渲染元素属性
      render_helper(element, template);

      // 特殊元素的处理
      switch (element_name) {
        case "fieldset":
          // 为fieldset添加标题
          if (template.title) {
            let legend = document.createElement("legend");
            element.appendChild(legend);
            thin_render(legend, template.title);
          }
          break;
        case "textarea":
          element.name = template.textarea;
          break;
        case "a":
          // 处理链接地址
          if (template.href)
            element.setAttribute(
              "href",
              render_content(element, template.href)
            );
          break;
        default:
          break;
      }

      // 渲染元素内容
      if (typeof template[element_name] === "string") {
        // 数字格式化
        if (template.NumberFormat) {
          let content = render_content(container, template[element_name]);
          let text = new Intl.NumberFormat(
            "en-US",
            template.NumberFormat
          ).format(content);
          element.innerText = text;
        }
        // 日期时间格式化
        else if (template.DatetimeFormat) {
          let content = render_content(container, template[element_name]);
          let text = datatimeformat(content, template.DatetimeFormat);
          element.innerText = text;
        }
        // 字符串模板
        else string_template(element, template[element_name]);
      } else thin_render(element, template[element_name]);

      // 浮动提示框处理
      if (template.float) {
        element.addEventListener("mouseover", (e) => {
          let float = document.createElement("float");
          e.target.appendChild(float);
          thin_render(float, template.float);
        });
        element.addEventListener("mouseout", (e) => {
          thin("float", e.target).remove();
        });
      }

      // 执行渲染后的钩子函数
      template?.after?.({ container: element, data: nearest_data(element) });
    }
  }
}
